package com.xzy.generic.bad.example.d;

import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ApplicationEventMulticaster;
import org.springframework.core.ResolvableType;

import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;

/**
 * 事件及其监听器管理
 *
 * @author xzy.xiao
 * @date 2023/3/6  13:59
 */
abstract class MyApplicationEventMulticaster implements ApplicationEventMulticaster {

    public final Map<Class<?>, Set<ApplicationListener<?>>> event2ListenerMap = new HashMap<>();

    // ========== 监听器管理 ==========

    @Override
    public void addApplicationListener(ApplicationListener<?> listener) {

        // 解析监听器监听的事件
        ResolvableType resolvableType = ResolvableType
                .forClass(listener.getClass())
                .as(ApplicationListener.class)
                .getGeneric();
        Class<?> resolve = resolvableType.resolve();
        System.out.printf("监听器 %s 监听的事件为 %s\n", listener, resolvableType);

        // 记录监听各个事件的处理器
        Set<ApplicationListener<?>> eventListeners = this.event2ListenerMap.getOrDefault(resolve, new LinkedHashSet<>());
        eventListeners.add(listener);
        this.event2ListenerMap.put(resolve, eventListeners);
    }

    // ========== 事件管理 ==========

    @Override
    public void multicastEvent(ApplicationEvent event) {
        // 查找监听该事件的监听器
        ResolvableType resolvableType = ResolvableType.forInstance(event);
        Set<ApplicationListener<?>> eventListeners = event2ListenerMap.getOrDefault(resolvableType.resolve(), new LinkedHashSet<>());

        // 将事件传递给监听器
        for (ApplicationListener<?> eventListener : eventListeners) {
            System.out.printf("向监听器 %s 传递事件 %s\n", eventListener, event);
            doInvokeListener(eventListener, event);
        }
    }

    @SuppressWarnings({"rawtypes", "unchecked"})
    private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
        listener.onApplicationEvent(event);
    }

    // ========== 测试 ==========

    public static void main(String[] args) {
        ApplicationEventMulticaster applicationEventMulticaster = new MyApplicationEventMulticaster() {
            @Override
            public void addApplicationListenerBean(String listenerBeanName) {

            }

            @Override
            public void removeApplicationListener(ApplicationListener<?> listener) {

            }

            @Override
            public void removeApplicationListenerBean(String listenerBeanName) {

            }

            @Override
            public void removeAllListeners() {

            }

            @Override
            public void multicastEvent(ApplicationEvent event, ResolvableType eventType) {

            }
        };

        // 注册监听器
        applicationEventMulticaster.addApplicationListener(new XxxEventListener());

        // 传播事件
        applicationEventMulticaster.multicastEvent(new XxxEvent("xxx"));
    }
}
